#ifndef _GUI_OBJECT_H_
#define _GUI_OBJECT_H_

#include "../../tools/Point.h"
#include "../../input/Keys.h"
#include "../../draw/DrawObject.h"
#include "../../tools/xml/ticpp.h"
#include <string>

//Enums for dynamic alignment
enum ALIGNMENT {
	TOP,
	BOTTOM,
	LEFT,
	RIGHT,
	HORIZ_MIDDLE,	//Centered left and right
	VERT_MIDDLE,	//Centered top and bottom
	ABSOLUTE	//No dynamic alignment
};

//Forward declaration to reduce dependencies
class Frame;

/**
	Base class for any GUI object. Text, Picture, and Button all inherit from this.
	Defines the interface and some common variables that all subclasses will have.
	
	inherits drawPos and color from OrthoObject
*/
class Object: public OrthoObject {
public:
	Object(float x = 0, float y = 0, float z = 0, float width = 0, float height = 0, KEY_TYPE key = KEY_VOID, ALIGNMENT horizalign = ABSOLUTE, ALIGNMENT vertalign = ABSOLUTE);
	virtual ~Object()	{}
	fVec2D dimensions;						//The real estate (width and height) this object will occupy. Used for hit test
	KEY_TYPE myKey;						//The key press that corresponds with this object
	ALIGNMENT horizAlignment, vertAlignment;	//The vertical and horizontal alignment attributes for dynamic alignment
	float padding;							//The padding for an offset from some alignments. Works on all both axes
	
	bool operator<(const Object& o);			//For drawing order
	
//Interface Functions
	virtual void onLeftClick() = 0;			//When left clicked
	virtual void onKeyPress() = 0;			//When your button is pressed
	virtual void onRollOver() = 0;			//When the mouse is over the top of you
	virtual void onRealign(float minX, float maxX, float minY, float maxY) = 0;	//When the window resizes, align appropriately
	virtual void enable();					//Be drawable
	virtual void disable();					//Don't be drawable
	virtual void loadFromXML(ticpp::Node* node, int drawDepth, Frame* f);	//Load this from a node at drawDepth for f
};

/**
	functor for seeing if 2 pointers to objects are "less than"
*/
struct ObjectPointerLessThan {
	bool operator()(Object* a, Object* b) const;
};

/** 
	functor to see if an object's key is the desired one
*/
struct ObjectKeyEqual {
	KEY_TYPE key;
	ObjectKeyEqual(KEY_TYPE b);
	bool operator()(const Object* o);
};

/**
	functor to see if an object's hit box contains (x,y)
*/
struct ObjectClickHit {
	int x, y;
	ObjectClickHit(float, float);
	bool operator()(const Object* o);
};

// Sets a to the appropriate alignment from the passed in str, horiz = true when for horizontal, false when for vertical
void getAlignment(ALIGNMENT&a, const std::string &str, bool horiz = true);

#endif
